<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="">
    <meta name="author" content="">

    <title>Three.js Texture Mapping</title>
    
    <style type="text/css">
      html { overflow: hidden; }
      body { margin: 0; padding: 0; overflow: hidden; font-family: Monospace; font-size: 13px; line-height: 20px; color: #333; }
      #info { text-align: center; position: absolute; top: 0; width: 100%; padding: 5px; }

      a { color: #0088cc; text-decoration: none; }
      a:hover, a:focus { color: #005580; text-decoration: underline; }

      #texture { position: absolute; top: 50%; left: 80px; margin-top: -160px; width: 560px; height: 280px; border: 1px solid #333; background-size: contain; }

      .color-map { background-image: url('images/planets/earth_atmos_2048.jpg'); }
      .normal-map { background-image: url('images/planets/earth_normal_2048.jpg'); }
      .specular-map { background-image: url('images/planets/earth_specular_2048.jpg'); }
      .no-map { border: none !important; }
      .all-maps { background-image: url('images/planets/all-maps.png'); border: none !important; }

    </style>

  </head>

  <body>

    <div id="container"></div>
    
    <div id="texture" class="color-map"></div>

    <script src="three/three.min.js"></script>
    <script src="three/OrbitControls.js"></script>
    <script src="three/WebGL.js"></script>
    <script src="three/libs/dat.gui.min.js"></script>
    <script src="three/libs/tween.min.js"></script>


    <script>

      if ( !WEBGL.isWebGLAvailable() ) {
        document.body.appendChild( WEBGL.getWebGLErrorMessage() );
      }

      var container;

      var camera, controls, scene, renderer;

      var helper, mesh, dirLight, dirLight2, lightGroup, dLightHelper, dLightHelper2;

      var colorMap, normalMap, specMap, alphaMap, whiteMap, flatNormalMap;

      var mouseX = 0, mouseY = 0;

      var clock = new THREE.Clock();

      var windowHalfX = window.innerWidth / 2;
      var windowHalfY = window.innerHeight / 2;

      var FLOOR = -110;

      var theta = 0;
      var animating = false;

      init();
      animate();

      function init() {

        container = document.getElementById( 'container' );

        renderer = new THREE.WebGLRenderer( { antialias: true, alpha: true } );
        renderer.setClearColor( 0x000000, 0 );
        renderer.setSize( window.innerWidth, window.innerHeight );

        camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 100000 );
        camera.position.set(0, 0, 250);

        controls = new THREE.OrbitControls( camera, renderer.domElement );
        controls.enableKeys = false;
        controls.screenSpacePanning = true;

        scene = new THREE.Scene();


        // add objects here


        // Ambient light
        var light = new THREE.AmbientLight( 0xffffff ); // soft white light
        scene.add( light );


        lightGroup = new THREE.Object3D();

        dirLight = new THREE.DirectionalLight( 0xdddddd, 0.8 );
        dirLight.position.set( -100, 80, 80 );
        lightGroup.add( dirLight );

        dirLight2 = new THREE.DirectionalLight( 0xdddddd, 0.8 );
        dirLight2.position.set( 100, 80, -80 );
        lightGroup.add( dirLight2 );

        scene.add(lightGroup);


        // dLightHelper = new THREE.DirectionalLightHelper( dirLight, 15 );
        // scene.add( dLightHelper );

        // dLightHelper2 = new THREE.DirectionalLightHelper( dirLight2, 15 );
        // scene.add( dLightHelper2 );


        // var tween = new TWEEN.Tween(dirLight.position)
        //   .to({x: 80}, 1500)
        //   .easing(TWEEN.Easing.Cubic.InOut)
        //   .yoyo(true)
        //   .delay( 300 )
        //   .repeat( Infinity );
        //   .start();

        // tween.onUpdate(function(){ dLightHelper.update(); })

        // Ground
        // helper = new THREE.GridHelper( 200, 40 );
        // helper.setColors( 0x000000, 0x808080 );
        // helper.position.y = FLOOR;
        // scene.add( helper );


        var x = document.createElement( "canvas" );
        var xc = x.getContext( "2d" );
        x.width = x.height = 128;
        xc.fillStyle = "white";
        xc.fillRect( 0, 0, x.width, x.height );

        whiteMap = new THREE.Texture( x );
        whiteMap.needsUpdate = true;



        var x2 = document.createElement( "canvas" );
        var xc2 = x2.getContext( "2d" );
        x2.width = x2.height = 128;
        xc2.fillStyle = "rgb(127,127,255)";
        xc2.fillRect( 0, 0, x2.width, x2.height );

        flatNormalMap = new THREE.Texture( x2 );
        flatNormalMap.needsUpdate = true;



        var loader = new THREE.TextureLoader();

        colorMap = loader.load( "images/planets/earth_atmos_2048.jpg" );
        specMap = loader.load( "images/planets/earth_specular_2048.jpg" );
        normalMap = loader.load( "images/planets/earth_normal_2048.jpg" );
        alphaMap = loader.load( "images/planets/earth_alpha_2048.jpg" );
        

        // var material  = new THREE.MeshPhongMaterial( { ambient: 0xffffff, color: 0xffffff , specular: 0x333333, shininess: 15, map: colorMap } );

        var material = new THREE.MeshPhongMaterial({
          color: 0xeeeeee,
          specular: 0x333333,
          shininess: 15,
          map: colorMap,
          specularMap: whiteMap,
          normalMap: flatNormalMap,
          alphaMap: whiteMap
        });

        // var material  = new THREE.MeshBasicMaterial( { color: 0xffffff, map: colorMap } );

        // var geometry = new THREE.BoxGeometry( 80, 80, 80 );
        var geometry = new THREE.SphereGeometry( 60, 32, 24 );

        mesh = new THREE.Mesh( geometry, material );
        mesh.position.set(100,0,40);
        // mesh.position.set(80,-20,80);
        mesh.rotation.y = - Math.PI / 6;
        mesh.rotation.x = Math.PI / 12;
        scene.add( mesh );


        // helper = new THREE.WireframeHelper( mesh, 0xff0000 );
        // scene.add( helper );

        // setupTween();
        // setupGui();



        container.appendChild( renderer.domElement );


        document.addEventListener( 'mousemove', onDocumentMouseMove, false );

        //

        window.addEventListener( 'resize', onWindowResize, false );

      }


      // Tween.js
      // http://sole.github.com/tween.js/examples/03_graphs.html
      // http://learningthreejs.com/data/tweenjs_for_smooth_animation/tweenjs_for_smooth_animation.html
      // http://learningthreejs.com/blog/2011/08/17/tweenjs-for-smooth-animation/

      function setupTween() {
        var update  = function(){ mesh.rotation.y = current.y; }

        var current = { y: 0 };
        var target = { y: Math.PI / 12 };

        var tween = new TWEEN.Tween(current)
          .to(target, 1000).delay(4000)
          .easing(TWEEN.Easing.Cubic.InOut)
          .onUpdate(update);

        var tween2 = new TWEEN.Tween(current)
          .to({ y: -Math.PI / 12 }, 1000).delay(4000)
          .easing(TWEEN.Easing.Cubic.InOut)
          .onUpdate(update);

        tween.chain(tween2);
        tween2.chain(tween);

        tween.start();
      }

      function setupGui() {
        // dat.GUI debugging -----------------------------------------
        
        var opts = {
          normalScale: 1,
          animating: false
        }

        var gui = new dat.GUI();
        var f1 = gui.addFolder('material options');
        f1.add(opts, 'normalScale', -3, 3).onChange(function(val){ mesh.material.normalScale.set(val,val); });
        f1.add(opts, 'animating').onChange(function(val){ animating = val; });
        f1.open();
      }


      function onWindowResize() {

        windowHalfX = window.innerWidth / 2;
        windowHalfY = window.innerHeight / 2;

        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();

        renderer.setSize( window.innerWidth, window.innerHeight );

      }

      function onDocumentMouseMove( event ) {

        mouseX = ( event.clientX - windowHalfX );
        mouseY = ( event.clientY - windowHalfY );

      }

      //

      function animate() {
        requestAnimationFrame( animate );
        render();
        TWEEN.update();
        controls.update();
      }

      function render() {

        var delta = clock.getDelta();

        // lightGroup.rotation.y += 0.06;
        lightGroup.rotation.y += 3 * delta;

        if (animating) {
          // mesh.rotation.y -= 0.006;
          mesh.rotation.y -= 0.015;
        }

        renderer.render( scene, camera );

      }



      var step = 1;

      function applyStep(step) {
        // console.log(step);
        if (step == 1) {
        }
        else if (step == 2) {
          // COLOR MAP
          mesh.material.map = colorMap;
          mesh.material.normalMap = flatNormalMap;
          mesh.material.specularMap = whiteMap;
          mesh.material.needsUpdate = true;

          mesh.material.color.setHex(0xeeeeee);

          document.querySelector("#texture").className = 'color-map';
        }
        else if (step == 3) {
          // NORMAL MAP
          mesh.material.map = whiteMap;
          mesh.material.normalMap = normalMap;
          mesh.material.specularMap = whiteMap;
          mesh.material.needsUpdate = true;

          mesh.material.color.setHex(0x777777);

          document.querySelector("#texture").className = 'normal-map';
        }
        else if (step == 4) {
          // SPECULAR MAP
          mesh.material.map = whiteMap;
          mesh.material.normalMap = flatNormalMap;
          mesh.material.specularMap = specMap;
          mesh.material.needsUpdate = true;

          mesh.material.color.setHex(0x777777);

          document.querySelector("#texture").className = 'specular-map';
        }
        else if (step == 5) {
          // ALL MAPS
          mesh.material.map = colorMap;
          mesh.material.normalMap = normalMap;
          mesh.material.specularMap = specMap;
          mesh.material.needsUpdate = true;

          mesh.material.color.setHex(0xeeeeee);

          document.querySelector("#texture").className = 'all-maps';
          // document.querySelector("#texture").style.display = 'none';
        }
      }

      onmessage = function(e) {
        // paused = (e.data == 'pause' || e.data == 'slide:stop');
        step = e.data.director.args[0];
        applyStep( step );
      };

      function forward() {
        step++;
        if (step > 5) { step = 5; return; }
        applyStep(step);
      }

      function back() {
        step--;
        if (step <= 0) { step = 1; return; }
        applyStep(step);
      }

      // Controls for stand-alone
      window.addEventListener('keydown', function (e) {
        if (e.keyCode == 38 || e.keyCode == 37) back();
        if (e.keyCode == 40 || e.keyCode == 39) forward();
      });
      

    </script>


  </body>
</html>
